package com.kaisu.blog.web.filter;

import com.kaisu.blog.application.properties.AuthProperties;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

@Component
@RequiredArgsConstructor
public class StaticContentFilter implements Filter {
    private final AuthProperties authProperties;
    private final List<String> fileExtensions = Arrays.asList("html", "js", "json", "csv", "css", "png", "svg", "eot", "ttf", "woff", "appcache", "jpg", "jpeg", "gif", "ico", "webp");

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        doFilter((HttpServletRequest) request, (HttpServletResponse) response, chain);
    }

    private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        String path = request.getServletPath();
        boolean isLocalStatic = path.startsWith(authProperties.getPrefix()) ||
                                authProperties.getPermitStatic().stream().anyMatch(path::contains) ||
                                authProperties.getPermitMethod().stream().anyMatch(path::contains);
        boolean isResourceFile = !isLocalStatic && fileExtensions.stream().anyMatch(path::contains);
        if (isLocalStatic) {
            chain.doFilter(request, response);
        } else if (isResourceFile) {
            resourceToResponse("static" + path, response);
        } else {
            resourceToResponse("static/index.html", response);
        }
    }

    private void resourceToResponse(String resourcePath, HttpServletResponse response) throws IOException {
        try (InputStream inputStream = Thread.currentThread()
                .getContextClassLoader()
                .getResourceAsStream(resourcePath)) {
            if (inputStream == null) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND, HttpServletResponse.SC_NOT_FOUND + " " + HttpServletResponse.SC_NOT_FOUND);
                return;
            }
            //headers
            if (resourcePath.endsWith(".html")) {
                response.setContentType("text/html;charset=UTF-8");
            }
            if (resourcePath.endsWith(".css")) {
                response.setContentType("text/css;charset=UTF-8");
            }
            if (resourcePath.endsWith(".js")) {
                response.setContentType("text/javascript;charset=UTF-8");
            }
            if (resourcePath.endsWith(".svg")) {
                response.setContentType("image/svg+xml");
            }
            inputStream.transferTo(response.getOutputStream());
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                response.getOutputStream().write(buffer, 0, bytesRead);
            }
        }
    }
}